[ 筆記 ] - API 基礎、JSON、curl 指令


Posted by krebikshaw on 2020-07-03

API 是什麼?

API 就是一段網址,只要照著對方要求的規格來輸入正確的網址,就能取得對方提供的資料。配合 HTTP 協定的規範,就可以達成更多資料交換的功能。

Server 要求的規格是什麼?

依據 Server 功能的不同,會要求的規格也會不同。
拿 Twitch 這個遊戲直播平台來舉例,他們有提供其中一項 熱門遊戲查詢 的功能。
只要輸入這段網址 https://api.twitch.tv/kraken/games/top 他就會依照熱門程度來提供遊戲資料給你。

除了這段規定的網址以外,Server 還說你可以加上條件來決定要你想列出前幾熱門的遊戲,只要在網址後面加上 limit=<你想列出的數量> ,所以如果我希望列出前十熱門的遊戲,網址就會變成這樣 https://api.twitch.tv/kraken/games/top?limit=10

其他像是訂房網站啦,可能就會讓你輸入指定網址來取得訂房資訊,加上條件或許能列出某某地區,某某時間或其他條件下查詢的結果。這些功能都是依據 Server 所提供給我們的,它提供哪些功能,我們就只能使用這些功能,因為總不可能連會員帳密、會員資料、手機號碼等等都公開出來。所以才會說,你只能取得對方願意讓你取得的資料。

Server 可以自由決定要讓使用者獲取哪些資訊,並且要提供使用者一份明確的 API 文件,使用者才會曉得如何透過 API 來取得 Server 提供的資料。

Server 提供的資料是什麼?

Server 會提供的就是它們資料庫有的資料,以遊戲直播平台來說,提供的就是與遊戲直播相關的訊息,熱門遊戲、熱門主播、遊戲頻道資訊、遊戲討論資訊...。若是訂房網站,提供的就會是與房間相關的資訊,價格、地點、房型、交通...等等。

你會發現!這些其實跟你實際去這些網站上會查到的資料差不多啊。因為不論是從它們網站上查詢,還是用 API 去取得 Server 的資料,都是存取相同的資料庫,所以網站上面顯示的資料內容,跟 API 提供的資料,才會大同小異。

API 簡介

  • Application Programming Interface 應用程式介面
    依據使用環境的不同有所區別:
    • 軟硬體廠商的 API
    • 有作業系統用的 API ,用於傳輸、寫入、讀取資料…等等電腦上一切的操作
    • 自己團隊內部用的 API
    • 對於網頁來說就是 Web API,是基於 http 協定下運作的 API

一個好的 API 應該要有下列條件

  • 完整的 API 文件說明與規範
  • 有範例程式,解釋如何運用於應用程式中
  • 有教學指引,一步一步帶領開發者學習使用 API
  • 合理的命名規則
  • 適當的防呆措施、必須預防開發者在錯誤使用時,也不會造成嚴重的傷害
  • 一開始就要有清楚的規劃、使用情境,因為一但更新或改動,客戶端都要做相對的審視與修改。

Web API 實際上最常應用的場景

  • 會員登入
  • 社群嵌入
    • 分享、按讚按鈕、嵌入貼文、留言板、影音
    • 例如:Facebook Graphic
  • 資料嵌入
    • 例如:Yahoo 氣象、Google 地圖

以網站來說,最常用的應該是登入系統,現在不管哪個網站,在會員登入頁,大部分都會有 Facebook 跟 Google 登入按鈕,這麼做對開發者、用戶、甚至是供應商,都是有利的狀況:

  • 開發者: 取自大神的登入功能,安全又省力
  • 用戶: 幾乎每個人都有帳號,無須花時間填寫會員資料
  • API 供應者:
    • 免費的廣告
    • 獲取使用者操作與使用習慣的資料,再進行分析,以方便投放更精準的廣告

參考資料:
什么是API,接口?
API設計和應用程式設計的不同?

RESTful API

RESTful API 是一種 API 的設計風格

在 「非」RESTful 的設計底下我們可能看到:

  • GET + /Get_allArticle: 獲取 所有文章
  • GET + /Get_Article/5: 獲取 id 為 5 的文章
  • POST + /Create_Article: 新增 文章
  • POST + /Delete_Article/5: 刪除 id 為 5 的文章

這些方式是將 http method 「動詞」寫在 URL 前面

在「有」RESTful 的設計底下我們可能看到:

  • GET + /articles: 獲取 所有文章
  • GET + /articles/5: 獲取 id 為 5 的文章
  • POST + /articles: 新增 文章
  • DELETE + /articles/5: 刪除 id 為 5 的文章
  • PATCH + /articles/5: 修改 id 為 5 的文章部分內容
  • PUT + /articles/5: 更新 id 為 5 的文章全部內容 ( 換句話說,就是覆蓋 )

request 要符合 「 語易化的動詞 Method 」 + 「 名詞 URL 」的格式

CRUD 原則
雖然只用 GET 跟 POST 也可以達到以上功能,但充份善用 HTTP Method 可以讓開發者更快速地了解如何使用此 API,也符合 CRUD 原則的、分別是
Create (Post):新增資料時用
Read (Get):取得資料時用
Update (Put / Patch):利用更新的方式於"指定位置"新增一項資料 / 在現有的資料欄位中,增加或部分更新一筆新的資料
Delete (Delete):刪除資料時用
我們就把這種風格稱為 RESTful API。

正確的動詞搭配明確的名詞,讓人清楚知道這個 request 的目的是什麼

參考資料:休息(REST)式架構? 寧靜式(RESTful)的Web API是現在的潮流?

串接 API 實作重點

因為取得的資料不一定保證正確,所以需要一些除錯手段來防止顯示出有誤的資料

  • 判斷一:responseStatusCode 要是 2xx 才執行,不是 2xx 開頭的要報錯
if (response.statusCode >= 200 && response.statusCode < 300) {
  //...
} else {
  //...
}
  • 判斷二:response 如果有 error 要報錯:
request.get(error, response, body)
  .then(response => {
    //...
  }).catch { error => {
    //...
  })
  • 要 POST 或者 PATCH 的時候,要告訴 server 你要帶的資料型態
    • 需要用一個參數叫 content-type
      1. 若是要帶表單格式: application/x-www-form-urlencoded
      2. 若是要夾帶檔案: multipart/form-data
      3. 若是要帶 JAON 格式:application/json
題目要求要使用 Node 執行程式的同時,可以達到各種參數的功能
node hw2.js list // 印出前二十本書的 id 與書名
node hw2.js read 1 // 輸出 id 為 1 的書籍
node hw2.js delete 1 // 刪除 id 為 1 的書籍
node hw2.js create "I love coding" // 新增一本名為 I love coding 的書
node hw2.js update 1 "new name" // 更新 id 為 1 的書名為 new name
  • 一般正常的寫法會是:
const request = require('request');

const argv = process.argv;
const inputMethod = argv[2];

if (!inputMethod) console.log('請輸入完整訊息!')
// 用 switch 來區別不同的 method 要做相應的處理
switch (inputMethod) {
  case 'list':
    doList();
    break;
  case 'read':
    deRead(argv);
    break;
  case 'delete':
    doDelete(argv);
    break;
  case 'create':
    doCreate(argv);
    break;
  case 'update':
    doUpdate(argv);
    break;
  default:
    console.log('輸入內容有誤喔!請再試一次。')
}
// 每個不同的 case 都要一個新的 function,程式會變得很長很雜
function doList() {
  request.get('https://lidemy-book-store.herokuapp.com/books?_limit=20')
    .then( response => {

    }).catch( error => {

    })
}

function doRead(argv) {

}

function doDelete(argv) {

}
   .
   .
   .
  • 學姐使用的方法是:
const request = require('request');
const process = require('process');
const rp = require('request-promise');

const baseUrl = 'https://lidemy-book-store.herokuapp.com/books';
const num = 20;
const method = process.argv[2];
const firstKey = process.argv[3];
const secondKey = process.argv[4];

// 先定義好取得 JSON 後如何處理資料
function getJson(body) {
  const json = JSON.parse(body);
  if (json.length > 1) {
    json.map(element => console.log(element.id, element.name));
  } else {
    console.log(json.id, json.name);
  }
}

// 用非常簡潔的方式寫出 5 情況需要做哪些事情,超整潔超乾淨!
if (method === 'list') {
  rp(`${baseUrl}?_limit=${num}`)
    .then(htmlString => getJson(htmlString));
}
if (method === 'read') {
  rp(`${baseUrl}/${firstKey}`)
    .then(htmlString => getJson(htmlString));
}
if (method === 'delete') request.delete(`${baseUrl}/${firstKey}`);
if (method === 'create') request.post(baseUrl).form({ name: firstKey });
if (method === 'update') request.patch(`${baseUrl}/${firstKey}`).form({ name: secondKey });

資料格式 XML & JSON

XML

  • Extensible Markup Language
  • 跟 HTML 有點像、都是標記語言 Markup Language,特色是「 內容用前後標籤包起來 」,因為此格式檔案較大、且不好閱讀,所以現代開發比較少人用 XML。

JSON

  • JavaScript Object Notation
  • 乍看跟 JavaScript 的物件很像,但 key 值必須要用雙引號 "key" 包起來
  • JSON 字串可以包含 陣列 ( 用中括號 [ ] ) 以及 物件 ( 用大括號 { } )
  • 小規定:
    • JSON 格式不能使用註解
    • Vaule 值沒有辦法放 function
  • JSON Editor online

JSON 資料處理

JSON 字串解析成 JavaScript 物件

JSON.parse():可以將 JSON 字串解析成 JavaScript 物件

// 宣告字串須使用 '' 括起來,否則就會變成是 JavaScript object 了
// 如在不同行必須在每行結尾處加上 \,否則會產生 SyntaxError
var jsonString = '{ \
    "number": "1020501", \
    "name": "小明", \
    "age": 32, \
    "sex": "M", \
    "interest": [ \
        "網頁設計", \
        "撰寫文章" \
    ] \
}';

// 將 JSON 字串解析成 JavaScript 值,這樣就可使用 JavaScript 進行操作了
var member = JSON.parse(jsonString);

// 取得物件的指定值
console.log(
    member.name + ', ' +
    member.interest[0]
);

輸出: 
小明, 網頁設計

JSON.parse() 可傳入 第二個參數 來過濾要轉換的資料

  • 第一個參數:String 名稱
  • 第二個參數:
    • 可以傳入一個用來過濾資料的 function
var jsonString = '{ \
    "number": "1020501", \
    "name": "小明", \
    "age": 32, \
    "sex": "M", \
    "interest": [ \
        "網頁設計", \
        "撰寫文章" \
    ] \
}';

// 使用第二個參數 function 方式,排除 age 特性不被包括在物件
var member = JSON.parse(jsonString, function(key, value) {
    if (key === "age") return undefined;

    return value;
});

// 取得物件
console.log(member);

輸出:
Object {number: "1020501", name: "小明", sex: "M", interest: ["網頁設計", "撰寫文章"]}

物件序列化成 JSON 字串

JSON.stringify():可以將 JavaScript 物件序列化成 JSON 字串:

// JavaScript 物件
var member = {
    "number": "1020501",
    "name": "小明",
    "age": 32,
    "sex": "M",
    "interest": [
        "網頁設計",
        "撰寫文章"
    ]
};

console.log(
    JSON.stringify(member)  // 序列化成 JSON 字串
);

輸出:
 {"number":"1020501","name":"小明","age":32,"sex":"M","interest":["網頁設計","撰寫文章"]}

JSON.stringify() 可傳入 第二個參數 來過濾要轉換的資料

  • 第一個參數:Object 名稱
  • 第二個參數:
    • 可以傳入一個用來過濾資料的 function
  // JavaScript 物件
  var member = {
    "number": "1020501",
    "name": "小明",
    "age": 32,
    "sex": "M",
    "interest": [
        "網頁設計",
        "撰寫文章"
    ]
  };

// 使用第二個參數 function 方式,排除 age 特性不被序列為 JSON 字串
  console.log(
    JSON.stringify(member, function(key, value) {
        if (key === "age") return undefined;

        return value;
    })
);

輸出: 
{"number":"1020501","name":"小明","sex":"M","interest":["網頁設計","撰寫文章"]}
  • 或傳入 array 來指定要轉換哪些資料
// 使用第二個參數 array 方式,指定要被序列為 JSON 字串的特性
console.log(
    JSON.stringify(member, ["number", "name"])
);

輸出:
{"number":"1020501","name":"小明"}

參考資料:JSON 格式與 JavaScript 解析教學範例

curl 方法

隨便看一個 Web API 文件,一定都會看到上面用 curl 示範如何發出正確的 request,因為此做法最簡單、沒有任何門檻,只要在終端機 ( Terminal ) 輸入指令就可以發 request!
基本格式

curl [options] [URL...]

curl 參數

-I:只需要 response header (--header)

-o(小寫):下載 response 到新檔案 (--output)

-O(大寫):下載指定網址的檔案內容 (--remote-name)

-L:直接跟隨 Status Code 為 301 / 302 轉址後的網址

  • curl -L google.com

-X:使用 HTTP Method 來發出 request,後面要加上 GET/POST/PUT/DELETE/PATCH (--request)

-H:設定 request 要攜帶的 header

-S:靜音模式,不輸出任何東西 (--silent)

參考資料:
Linux Curl Command 指令與基本操作入門教學
linux指令 curl指令详解


#API







Related Posts

What Type of Laser Engraving Machine Should be Used for Stainless Steel Engraving?

What Type of Laser Engraving Machine Should be Used for Stainless Steel Engraving?

Switch between uppercase to lowercase

Switch between uppercase to lowercase

W13_作業四簡答題

W13_作業四簡答題


Comments